//
// Created by Never on 2019/11/1.
//
#include <gtest/gtest.h>
#define protected public
#define private public
#include "../SRC/MinimalSpanningForestWithCapCons.h"
class TestMinimalSpanningForestWithCapCons: public testing::Test{
public:
    // instance is presented in instance_for_msf_with_cap_cons.png
    std::vector<int> roots = {0, 2};
    std::vector<int> nodes = {1, 3, 4, 5};
    std::vector<int> partialRoots = {0, 2};

    std::vector<std::vector<int>> distances = {{0, 1, unConnected, 3, 1, 1},
                                               {1, 0, 3, 3, 3, 3},
                                               {unConnected, 3, 0, 1, 2, 3},
                                               {3, 3, 1, 0, 3, 3},
                                               {1, 3, 2, 3, 0, 3},
                                               {1, 3, 3, 3, 3, 0}};
    std::vector<int> demands = {2, 1, 2, 1, 1, 1};
    int vehicleCap = 2;
    MinimalSpanningForestWithCapCons<int> msf;
    TestMinimalSpanningForestWithCapCons():
    msf(roots, nodes, distances, demands, vehicleCap){}
    void checkInitialTable(const std::vector<bool> &expectedIsKnown, const std::vector<int> &expectedPrevious,
                           const std::vector<int> &expectedMinCost, const std::vector<int> &expectedDemandsInBranch,
                           const std::vector<int> &expectedDemandsInRoot, const std::vector<int> &expectedPreRoots,
                           const std::vector<int> &expectedFirstNodeInBranch)
    {
        ASSERT_EQ(expectedIsKnown, msf.isKnown);
        ASSERT_EQ(expectedMinCost, msf.minCost);
        ASSERT_EQ(expectedPrevious, msf.preNode);
        ASSERT_EQ(expectedDemandsInBranch, msf.demandsInBranch);
        ASSERT_EQ(expectedDemandsInRoot, msf.demandsInRoots);
        ASSERT_EQ(expectedPreRoots, msf.preRoot);
        ASSERT_EQ(expectedFirstNodeInBranch, msf.firstNodeInBranches);
    }
    void testInitialTableForAllRoots(){
        std::vector<bool> expectedIsKnown = {true, false, true, false, false, false};
        std::vector<int> expectedPrevious = {0, 0, 2, 2, 0, 0};
        std::vector<int> expectedMinCost = {0, 1, 0, 1, 1, 1};
        std::vector<int> expectedDemandsInBranch = {0, 0, 0, 0, 0, 0};
        std::vector<int> expectedDemandsInRoot = {0, 0, 0, 0, 0, 0};
        std::vector<int> expectedPreRoots = {0, 0, 2, 2, 0, 0};
        std::vector<int> expectedFirstNodeInBranch = {0, 0, 2, 2, 0, 0};
        checkInitialTable(expectedIsKnown, expectedPrevious, expectedMinCost, expectedDemandsInBranch,
                          expectedDemandsInRoot, expectedPreRoots, expectedFirstNodeInBranch);
    }
};
TEST_F(TestMinimalSpanningForestWithCapCons, InitialTable)
{
    msf.initialTable(partialRoots);

    testInitialTableForAllRoots();
}
TEST_F(TestMinimalSpanningForestWithCapCons, SolveStateOfGenerateMinimalSpanningForestSatisfyingCapCons)
{
    bool expectedIsSolved = true;

    auto isSolved = msf.minimalSpanningForestWithCapCons(partialRoots);

    ASSERT_EQ(expectedIsSolved, isSolved);
}
TEST_F(TestMinimalSpanningForestWithCapCons, CostOfGenerateMinimalSpanningForestSatisfyingCapCons)
{
    int expectedCost = 6;

    msf.minimalSpanningForestWithCapCons(partialRoots);
    auto cost = msf.getCost();

    ASSERT_EQ(expectedCost, cost);
}
TEST_F(TestMinimalSpanningForestWithCapCons, FeasibilityOfGenerateMSFSatisfyCapCons)
{
    msf.minimalSpanningForestWithCapCons(partialRoots);

    for(auto root: partialRoots)
        ASSERT_LE(msf.demandsInRoots[root], msf.demands[root]);
    for(auto node: nodes)
        ASSERT_EQ(true, msf.isKnown[node]);
}
TEST_F(TestMinimalSpanningForestWithCapCons, VehicleNumberOfMSF)
{
    std::map<int, int> expectedVehicleNumber({{0, 2}, {2, 2}});

    msf.minimalSpanningForestWithCapCons(partialRoots);
    auto vehicleNumber = msf.getDepotsToVehicleNumber();

    ASSERT_EQ(expectedVehicleNumber, vehicleNumber);
}
TEST_F(TestMinimalSpanningForestWithCapCons, NodesInEachRoot)
{
    std::map<int, std::vector<int>> expectedNodesInEachRoot({{0, {1, 4}}, {2, {3, 5}}});

    msf.minimalSpanningForestWithCapCons(partialRoots);
    auto nodesInEachRoot = msf.getNodesInEachRoot();

    ASSERT_EQ(expectedNodesInEachRoot, nodesInEachRoot);
}